﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using netCoreStudy.Dto.User;
using netCoreStudy.Entities;
using netCoreStudy.Entities.Base;
using netCoreStudy.Entities.Parameter;
using netCoreStudy.IService;
using Renci.SshNet.Messages.Authentication;

namespace netCoreStudy.Controllers
{
	/// <summary>
	/// 菜单管理 
	/// </summary>
	[ApiController]
	[Route("api/menu")]
	public class MenuController : BaseController<Menu, MenuDto, MenuParameter, AddMenuDto, UpdateMenuDto>
	{
		private readonly IMenuService _menuService;
		private readonly IUserService _userService;
		private readonly IRoleService _roleService;

		public MenuController(ILogger<MenuController> logger, IBaseService<Menu> baseService, IMapper mapper,
			IMenuService menuService, IUserService userService, IRoleService roleService)
			: base(logger, baseService, mapper)
		{
			_menuService = menuService;
			_userService = userService;
			_roleService = roleService;
		}

		/// <summary>
		/// 根据用户ID 递归获取menu菜单
		/// </summary>
		/// <returns></returns>
		[HttpGet("getMenusRecursion/{userId}")]
		public async Task<IActionResult> GetMenusRecursion(long userId)
		{
			User user = await _userService.GetOneByIdAsync(userId);
			long[] roleIds = user.UserRoles.Select(x => x.RoleId).ToArray();
			//Distinct() 数组去重
			long[] menuIds = (await _roleService.GetAllByIdsAsync(roleIds)).Select(x => x.RoleMenus)
				.SelectMany(x => x.ToArray()).Select(x => x.MenuId).Distinct().ToArray();
			List<Menu> list = await _menuService.GetAllSingle().Where(x => x.PId == 0 && menuIds.Contains(x.Id))
				.ToListAsync();
			List<MenuDto> listDtos = _mapper.Map<List<MenuDto>>(list);
			foreach (MenuDto menu in listDtos)
			{
				await GetMenus(menu);
			}

			return this.SuccessMsg("查询成功", listDtos);
		}

		/// <summary>
		/// 递归获得 菜单
		/// </summary>
		/// <param name="menu"></param>
		/// <returns></returns>
		private async Task GetMenus(MenuDto menu)
		{
			List<Menu> menus = await _menuService.GetAllSingle().Where(x => x.PId == menu.Id).ToListAsync();
			List<MenuDto> listDtos = _mapper.Map<List<MenuDto>>(menus);
			menu.Children.AddRange(listDtos);
			foreach (MenuDto m in listDtos)
			{
				GetMenus(m);
			}
		}
	}
}